package com.chinasoft.reposearch.util;

import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class RepoJsonCutter {
    /**
     * @param args [src, dst, cut]
     *             src: 源JSON文件路径
     *             dst: 目标文件路径
     *             cut: 截取前几条数据；如果为空，则截取所有数据
     */
    public static void main(String[] args) {
        if (args.length < 2 || args.length > 3) {
            System.out.println("Usage: java RepoJsonCutter <src> <dst> [<cut>]");
            return;
        }
        int cut = -1;
        try {
            if (args.length == 3) {
                cut = Integer.parseInt(args[2]);
                if (cut < 0) {
                    System.out.println("Cut must not be negative");
                    return;
                }
            }
        } catch (NumberFormatException e) {
            System.out.println("Incorrect cut number");
            return;
        }
        try {
            cutRepoJson(args[0], args[1], cut);
        } catch (FileNotFoundException e) {
            System.out.println("File not found");
        } catch (IOException e) {
            System.out.println("Incorrect Json Format");
        }
    }

    public static void cutRepoJson(String src, String dst, int cut) throws IOException {
        try (JsonReader reader = new JsonReader(new FileReader(src));
             JsonWriter writer = new JsonWriter(new FileWriter(dst))) {
            reader.beginArray();
            writer.beginArray();
            int i = 0;
            while ((cut < 0 || i++ < cut) && reader.hasNext()) {
                reader.beginObject();
                writer.beginObject();
                while (reader.hasNext()) {
                    String name = reader.nextName();
                    switch (name) {
                        case "owner", "name", "description", "primaryLanguage", "createdAt", "pushedAt" -> {
                            if (reader.peek().equals(JsonToken.NULL)) {
                                reader.nextNull();
                                writer.name(name).nullValue();
                            } else {
                                writer.name(name).value(reader.nextString());
                            }
                        }
                        case "stars", "forks", "watchers", "languageCount", "topicCount" -> {
                            if (reader.peek().equals(JsonToken.NULL)) {
                                reader.nextNull();
                                writer.name(name).nullValue();
                            } else {
                                writer.name(name).value(reader.nextLong());
                            }
                        }
                        case "isFork" -> writer.name(name).value(reader.nextBoolean());
                        case "languages", "topics" -> {
                            writer.name(name);
                            reader.beginArray();
                            writer.beginArray();
                            while (reader.hasNext()) {
                                reader.beginObject();
                                writer.beginObject();
                                writer.name(reader.nextName()).value(reader.nextString());
                                writer.name(reader.nextName()).value(reader.nextLong());
                                writer.endObject();
                                reader.endObject();
                            }
                            writer.endArray();
                            reader.endArray();
                        }
                        default -> reader.skipValue();
                    }
                }
                writer.endObject();
                reader.endObject();
            }
            writer.endArray();
        }
    }
}
